package cn.rulian.base.auth.controller;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.Colour;
import jxl.format.VerticalAlignment;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.rulian.base.auth.bo.Resource;
import cn.rulian.base.auth.bo.ResourceType;
import cn.rulian.base.auth.dao.ResourceDao;
import cn.rulian.base.auth.dao.ResourceTypeDao;
import cn.rulian.base.auth.service.ResourceService;
import cn.rulian.base.auth.service.RoleService;
import cn.rulian.base.auth.vo.ResourceVo;
import cn.rulian.base.common.dto.ExcelBook;
import cn.rulian.base.common.dto.ExcelSheet;
import cn.rulian.base.common.dto.Message;
import cn.rulian.base.common.util.xx;
import cn.rulian.base.common.vo.Result;
import cn.rulian.base.common.vo.TreeVo;

/**
 * 资源管理 Controller
 */

@Controller
@RequestMapping("/base/auth/resource")
public class ResourceController {
	
	@Autowired
	private ResourceService service;

	@Autowired
	private ResourceDao dao;
	
	@Autowired
	private ResourceTypeDao resourceTypeDao;

	@Autowired
	private RoleService roleService;
	
	private final String path="base/auth/resource_"; //页面基本路径

	/**
	 * 页面基本路径
	 */
	private String getPath()
	{
		return path;
	}
	
	/**
	 * 列表页面
	 */
	@RequestMapping("/listPage")
	public String listPage() {
		return this.getPath()+"list";
	}

	/**
	 * 查询(暂无用)
	 */
	@RequestMapping("/listData")
	@ResponseBody
	public Result listData(ResourceVo vo) {
		return service.query(vo);
	}

	/**
	 * 查询所有数据
	 */
	@RequestMapping("/findAll")
	@ResponseBody
	public Result findAll() {
		Sort sort = new Sort(Direction.ASC, "orderNum"); // 排序
		List<Resource> list = service.findAll(sort);
		for(Resource bo:list)
		{
			if(bo.getFather() != null)
			{
				bo.set_parentId(bo.getFather().getId());
			}
			bo.setRoleList(null);
			bo.setState(bo.getMenuState());
		}
		Result result = new Result();
		result.setRows(list);
		return result;
	}
	

	/**
	 * 查询所有数据,供下拉列表使用。
	 */
	@RequestMapping("/findAllForselect")
	@ResponseBody
	public List<TreeVo> findAllForselect() {
		
		//查询数据
		List<Resource> boList = dao.findByResourceType_codeOrderByOrderNum(ResourceType.MENU_CODE); //只查找菜单。
		
		//列表转换
		List<TreeVo> dtoList = new ArrayList<>();
		for(Resource bo:boList)
		{
			TreeVo dto = new TreeVo();
			dto.setId(bo.getId());
			dto.setText(bo.getName());
			dto.setIconCls(bo.getIconCls());
			if(bo.getFather() != null)
			{
				dto.set_parentId(bo.getFather().getId());
			}
			dtoList.add(dto);
		}
		
		//构造子结构
		for(TreeVo dto:dtoList)
		{
			for(TreeVo son:dtoList)
			{
				if(son.get_parentId() != null && son.get_parentId().longValue() == dto.getId().longValue())
				{ 
					List<TreeVo> children = dto.getChildren();
					if(children==null)
					{
						children = new ArrayList<>();
					}
					children.add(son);
					dto.setChildren(children);
				}
			}
		}
		
		//只保留顶层元素
		List<TreeVo> showList = new ArrayList<>();
		for(TreeVo dto:dtoList)
		{
			if(dto.get_parentId() == null)
			{
				showList.add(dto);
			}
		}
		
		return showList;
	}
	
	/**
	 * 列表页面
	 */
	@RequestMapping("/iconsPage")
	public String iconsPage() {
		return this.getPath()+"icons";
	}


	/**
	 * 增加页面
	 */
	@RequestMapping("/addPage")
	public String addPage(Model model, Long fatherId) {
		if(fatherId != null)
		{
			model.addAttribute("fatherId", fatherId);
		}
		
		Long nextOrderNum = service.getNextOrderNum(fatherId); //下一排序号
		model.addAttribute("nextOrderNum", nextOrderNum);
		
		return this.getPath()+"add";
	}
	
	/**
	 * 增加按钮页面
	 */
	@RequestMapping("/addButtonPage")
	public String addButtonPage(Model model, Long fatherId) {
		if(fatherId != null)
		{
			model.addAttribute("fatherId", fatherId);
			
			Resource father = service.findOne(fatherId);
			String authCode = father.getAuthCode();
			if(!xx.isEmpty(authCode))
			{
				model.addAttribute("authCode", authCode+"_");
			}
		}
		
		Long nextOrderNum = service.getNextOrderNum(fatherId); //下一排序号
		model.addAttribute("nextOrderNum", nextOrderNum);
		
		return this.getPath()+"addButton";
	}

	/**
	 * 增加
	 */
	@RequestMapping("/add")
	@ResponseBody
	public Message add(ResourceVo vo) {
		Message rm = new Message();
		Resource bo = vo.getObj();
		try {
			
			//权限码验重
			/*
			 * 暂不验重，有时页面中对不同Controller请求时，需要重复
			 * 
			if(!xx.isEmpty(bo.getAuthCode()))
			{
				Resource other = dao.findByAuthCode(bo.getAuthCode());
				if(other != null)
				{
					rm.setMsg("权限码重复，请修改！");
					rm.setCode(Message._ERROR);
					return rm;
				}
			}
			*/
			bo.setAddTime(new Date());
			service.save(bo);
			
			rm.setMsg("保存成功！");
			rm.setCode(Message._SUCCESS);
		} catch (Exception e) {
			rm.setMsg("保存失败，异常信息：<br/>" + e.toString());
			rm.setCode(Message._ERROR);
			e.printStackTrace();
		}
		return rm;
	}

	/**
	 * 修改页面
	 */
	@RequestMapping("/updatePage")
	public String updatePage(Model model, Long id) {
		model.addAttribute("bo", service.findOne(id));
		return this.getPath()+"update";
	}
	

	/**
	 * 修改页面
	 */
	@RequestMapping("/updateButtonPage")
	public String updateButtonPage(Model model, Long id) {
		model.addAttribute("bo", service.findOne(id));
		return this.getPath()+"updateButton";
	}

	/**
	 * 修改
	 */
	@RequestMapping("/update")
	@ResponseBody
	public Message update(ResourceVo vo,Long id) {
		Message rm = new Message();
		try {
			Resource obj = vo.getObj();
			Resource bo = service.findOne(id);
			
			//权限码验重
		/*	
		 *  暂不验重，有时页面中对不同Controller请求时，需要重复
		 *  
			if(!xx.isEmpty(obj.getAuthCode()))
			{
				Resource other = dao.findByAuthCode(obj.getAuthCode());
				if(other != null && other.getId().longValue() != bo.getId().longValue())
				{
					rm.setMsg("权限码重复，请修改！");
					rm.setCode(Message._ERROR);
					return rm;
				}
			}
		*/
			bo.setFather(obj.getFather());
			bo.setName(obj.getName());
			bo.setIconCls(obj.getIconCls());
			bo.setUrl(obj.getUrl());
			bo.setEnabled(obj.getEnabled());
			bo.setLocked(obj.getLocked());
			bo.setAuthCode(obj.getAuthCode());
			bo.setOrderNum(obj.getOrderNum());
			bo.setMenuState(obj.getMenuState());
			bo.setResourceType(obj.getResourceType());
			service.save(bo);
			
			rm.setMsg("保存成功！");
			rm.setCode(Message._SUCCESS);
		} catch (Exception e) {
			rm.setMsg("保存失败，异常信息：<br/>" + e.toString());
			rm.setCode(Message._ERROR);
			e.printStackTrace();
		}
		return rm;
	}

	/**
	 * 删除
	 */
	@RequestMapping("/delete")
	@ResponseBody
	public Message delete(Long ids[]) {
		Message rm = new Message();
		try {
			for(Long id:ids)
			{
				service.delete(id);
			}
			
			rm.setMsg("删除成功！");
			rm.setCode(Message._SUCCESS);
		} catch (Exception e) {
			rm.setMsg("删除失败！！！可能原因：<br/>1、已被【角色】使用。 <br/>2、有下级菜单。");
			rm.setCode(Message._ERROR);
			e.printStackTrace();
		}
		return rm;
	}
	
	/**
	 * 详情页面
	 */
	@RequestMapping("/detailPage")
	public String detailPage(Model model, Long id) {
		model.addAttribute("bo", service.findOne(id));
		return this.getPath()+"detail";
	}

	/**
	 * 导出Excel
	 * @throws Exception 
	 */
	@RequestMapping("/exportExcel")
	public void exportExcel(HttpServletResponse response,ResourceVo vo,String type) throws Exception {
		
		File file = new File("aaa.xls");
		jxl.write.WritableWorkbook book = Workbook.createWorkbook(file); //工作薄

		List<Resource> allDataList=service.QueryExcelData(vo); //取得导出数据
		ExcelBook<Resource> excelBook = this.buildExcelData(allDataList, type); //按维度进行数据加工
		String bookName = excelBook.getName(); //Excel文件名称
		List<ExcelSheet<Resource>> sheetList = excelBook.getSheetList(); //各Sheet列表
		if(sheetList!=null && sheetList.size() > 0)
		{
			for(ExcelSheet<Resource> excelSheet:sheetList)
			{
				String sheetName = excelSheet.getName(); //名称
				List<Resource> oneList = excelSheet.getDataList(); //数据列表
				
				jxl.write.WritableSheet sheet = book.createSheet(sheetName, 0); //工作表
				
				//设置行高
				sheet.getSettings().setDefaultRowHeight(350); //设置所有行默认行高
				sheet.setRowView(0, 700);//第1行 高度
				sheet.setRowView(1, 400);//第2行 高度
				
				//设置个别列宽
				//sheet.setColumnView(2, 12);//宽度设置
				
				//定义格式
				//主标题格式
				WritableCellFormat formatterTitle= new WritableCellFormat(); //标题格式
				formatterTitle.setAlignment(Alignment.CENTRE);//水平对齐
				formatterTitle.setVerticalAlignment(VerticalAlignment.CENTRE);//垂直对齐
				//WritableFont font = new WritableFont(WritableFont.createFont("ＭＳ Ｐゴシック"), 18, WritableFont.BOLD, false); //黑体
				WritableFont font = new WritableFont(WritableFont.TAHOMA, 18, WritableFont.BOLD, false);
				formatterTitle.setFont(font);
				
				//列标题格式
				WritableCellFormat formatterColumnTitle= new WritableCellFormat(); //列标题格式
				formatterColumnTitle.setAlignment(Alignment.CENTRE);//水平对齐
				formatterColumnTitle.setVerticalAlignment(VerticalAlignment.CENTRE);//垂直对齐
				formatterColumnTitle .setBackground(Colour.GRAY_25);//背景色
				formatterColumnTitle.setBorder(Border.ALL, BorderLineStyle.THIN);//边框线  所有边框 细线

				//普通内容格式
				WritableCellFormat formatterCon= new WritableCellFormat(); //内容格式
				formatterCon.setAlignment(Alignment.CENTRE);//水平对齐
				formatterCon.setVerticalAlignment(VerticalAlignment.CENTRE);//垂直对齐
				formatterCon.setBorder(Border.ALL, BorderLineStyle.THIN);//边框线  所有边框 细线
				
				//合计行格式
				WritableCellFormat formatterSum= new WritableCellFormat(); //合计格式
				formatterSum.setAlignment(Alignment.CENTRE);//水平对齐
				formatterSum.setVerticalAlignment(VerticalAlignment.CENTRE);//垂直对齐
				formatterSum.setBorder(Border.ALL, BorderLineStyle.THIN);//边框线  所有边框 细线
				WritableFont font_sum = new WritableFont(WritableFont.TAHOMA, 10, WritableFont.BOLD, false);
				formatterSum.setFont(font_sum);
				
				//输出标题
				sheet.mergeCells(0, 0, 8, 0); //合并单元格（标题）
				sheet.addCell(creatLabel(0,0,"资源管理（"+sheetName+"）",formatterTitle));

				//输出列标题
				int rowNum=1; //行号
				int columnNum=0; //列号
				
				sheet.addCell(creatLabel(rowNum,columnNum++,"序号",formatterColumnTitle));
				sheet.addCell(creatLabel(rowNum,columnNum++,"编号",formatterColumnTitle));
				sheet.addCell(creatLabel(rowNum,columnNum++,"名称",formatterColumnTitle));
				sheet.addCell(creatLabel(rowNum,columnNum++,"图标",formatterColumnTitle));
				sheet.addCell(creatLabel(rowNum,columnNum++,"URL",formatterColumnTitle));
				sheet.addCell(creatLabel(rowNum,columnNum++,"是否可用",formatterColumnTitle));
				sheet.addCell(creatLabel(rowNum,columnNum++,"是否锁定",formatterColumnTitle));
				sheet.addCell(creatLabel(rowNum,columnNum++,"排序号",formatterColumnTitle));
				sheet.addCell(creatLabel(rowNum,columnNum++,"所属菜单",formatterColumnTitle));
				
				//合计项
			
				if(oneList != null && oneList.size() > 0)
				{
					//SimpleDateFormat formatterDate = new SimpleDateFormat("yyyy-MM-dd"); //日期格式化
					//SimpleDateFormat formatterTime = new SimpleDateFormat("yyyy-MM-dd HH:mm"); //时间格式化
					//SimpleDateFormat formatterTime2 = new SimpleDateFormat("yyyy-MM-dd HH:mm"); //时间格式化2
					
					//展示数据
					String authCodeStr = ""; //权限码
					String nameStr = ""; // 名称
					String iconStr = ""; // 图标
					String urlStr = ""; // URL
					String enabledStr = ""; // 是否可用
					String lockedStr = ""; // 是否锁定
					String orderNumStr = ""; // 排序号
					String fatherStr = ""; // 所属菜单
					
					for(int i = 0; i < oneList.size(); i++)
			    	{
						Resource bo = oneList.get(i); 
						rowNum++;
						columnNum=0;
						
						//展示数据初始化
						authCodeStr = ""; //权限码
						nameStr = ""; // 名称
						iconStr = ""; // 图标
						urlStr = ""; // URL
						enabledStr = ""; // 是否可用
						lockedStr = ""; // 是否锁定
						orderNumStr = ""; // 排序号
						fatherStr = ""; // 所属菜单
						
						//展示数据赋值
						if(bo.getAuthCode() != null){	authCodeStr = bo.getAuthCode().toString();	} //权限码
	           		
						if(bo.getName() != null){	nameStr = bo.getName().toString();	} //名称
	           		
						if(bo.getIconCls() != null){	iconStr = bo.getIconCls().toString();	} //图标
	           		
						if(bo.getUrl() != null){	urlStr = bo.getUrl().toString();	} //URL
	           		
						if(bo.getEnabled() != null){	enabledStr = bo.getEnabled()?"开":"关";		} //是否可用
	           		
						if(bo.getLocked() != null){	lockedStr = bo.getLocked()?"开":"关";		} //是否锁定
	           		
						if(bo.getOrderNum() != null){	orderNumStr = bo.getOrderNum().toString();	} //排序号
	           		
						if(bo.getFather() != null){	fatherStr = bo.getFather().getName();	} //所属菜单
					
						
						
						//输出一行数据
			    		sheet.addCell(creatLabel(rowNum,columnNum++,(i+1)+"",formatterCon)); 
			    		sheet.addCell(creatLabel(rowNum,columnNum++,authCodeStr ,formatterCon)); // 权限码
			    		sheet.addCell(creatLabel(rowNum,columnNum++,nameStr ,formatterCon)); // 名称
			    		sheet.addCell(creatLabel(rowNum,columnNum++,iconStr ,formatterCon)); // 图标
			    		sheet.addCell(creatLabel(rowNum,columnNum++,urlStr ,formatterCon)); // URL
			    		sheet.addCell(creatLabel(rowNum,columnNum++,enabledStr ,formatterCon)); // 是否可用
			    		sheet.addCell(creatLabel(rowNum,columnNum++,lockedStr ,formatterCon)); // 是否锁定
			    		sheet.addCell(creatLabel(rowNum,columnNum++,orderNumStr ,formatterCon)); // 排序号
			    		sheet.addCell(creatLabel(rowNum,columnNum++,fatherStr ,formatterCon)); // 所属菜单
			    		
			    		//合计项累加
			    	}
					
					//表格增加合计项
					rowNum++;
					columnNum = 0;
					sheet.setRowView(rowNum, 400);//合计行 高度
		    		
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"",formatterSum)); 
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"" ,formatterSum)); // 编号
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"" ,formatterSum)); // 名称
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"" ,formatterSum)); // 图标
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"" ,formatterSum)); // URL
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"" ,formatterSum)); // 是否可用
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"" ,formatterSum)); // 是否锁定
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"" ,formatterSum)); // 排序号
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"" ,formatterSum)); // 所属菜单
    		
				}
			}
		}
		
		//-------------------------------

		book.write();
		book.close();

		FileInputStream f = new FileInputStream(file);
		byte[] fb = new byte[f.available()];
		f.read(fb);
		response.setHeader("Content-disposition", "attachment; filename=" + new String((bookName + ".xls").getBytes("gb2312"), "iso8859-1"));
		ByteArrayInputStream bais = new ByteArrayInputStream(fb);
		int b;
		while ((b = bais.read()) != -1)
		{
			response.getOutputStream().write(b);
		}
		response.getOutputStream().flush();
		f.close();
		
	}
	
	private Label creatLabel(int rowNum,int columnNum,String con,WritableCellFormat formatter) //行，列，内容 ，格式化
	{  
		 return new Label(columnNum, rowNum, con,formatter);   
	}  
	
	/**
	 * 从不同维度，构建Excel导出所需要的数据
	 */
	private ExcelBook<Resource> buildExcelData(List<Resource> list,String exportType)
	{
		ExcelBook<Resource> book = new ExcelBook<Resource>();
		
		
		if("all".equals(exportType))
		{//不分表
			book.setName("资源管理");
		}

		//根据维度（sheetName）不同，对数据分表
		Map<String,List<Resource>> map =new HashMap<String,List<Resource>>(); 
		String sheetName = null;
		for(Resource bo:list)
		{
		
	
			if("all".equals(exportType))
			{//不分表
				sheetName="全部";
			}
			
			List<Resource> dataList = map.get(sheetName);
			if(dataList==null)
			{
				dataList = new ArrayList<>();
			}
			dataList.add(bo);
			map.put(sheetName, dataList);
		}
		
		//转换Map,得到数据表列表
		List<ExcelSheet<Resource>> sheetList = new ArrayList<>();
		for (Map.Entry<String, List<Resource>> m : map.entrySet()) 
		{
			ExcelSheet<Resource> sheet = new ExcelSheet<Resource>();
			sheet.setName(m.getKey());
			sheet.setDataList(m.getValue());
			sheetList.add(sheet);
		} 
		
		if(sheetList.size()==0)
		{
			ExcelSheet<Resource> sheet = new ExcelSheet<Resource>();
			sheet.setName("全部");
			sheet.setDataList(new ArrayList<Resource>());
			sheetList.add(sheet);
		}
		
		book.setSheetList(sheetList);
		
		return book;
	}
	
}
